/*
 * SonarSource :: .NET :: Core
 * Copyright (C) 2014-2025 SonarSource Sàrl
 * mailto:info AT sonarsource DOT com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the Sonar Source-Available License for more details.
 *
 * You should have received a copy of the Sonar Source-Available License
 * along with this program; if not, see https://sonarsource.com/license/ssal/
 */
package org.sonarsource.dotnet.shared.plugins.protobuf;

import static org.sonarsource.dotnet.shared.plugins.SensorContextUtils.toTextRange;

import java.util.function.UnaryOperator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.cpd.NewCpdTokens;
import org.sonarsource.dotnet.protobuf.SonarAnalyzer;
import org.sonarsource.dotnet.protobuf.SonarAnalyzer.CopyPasteTokenInfo;

/**
  This class is responsible for reading/importing the CPD tokens that were generated by the C#/VB.NET analyzer.
 */
public class CPDTokensImporter extends ProtobufImporter<SonarAnalyzer.CopyPasteTokenInfo> {

  private static final Logger LOG = LoggerFactory.getLogger(CPDTokensImporter.class);

  private final SensorContext context;

  public CPDTokensImporter(SensorContext context, UnaryOperator<String> toRealPath) {
    super(SonarAnalyzer.CopyPasteTokenInfo.parser(), context, SonarAnalyzer.CopyPasteTokenInfo::getFilePath, toRealPath);
    this.context = context;
  }

  @Override
  void consumeFor(InputFile inputFile, CopyPasteTokenInfo message) {
    NewCpdTokens cpdTokens = context.newCpdTokens().onFile(inputFile);

    for (SonarAnalyzer.CopyPasteTokenInfo.TokenInfo tokenInfo : message.getTokenInfoList()) {
      toTextRange(inputFile, tokenInfo.getTextRange())
        .ifPresentOrElse(
          textRange -> cpdTokens.addToken(textRange, tokenInfo.getTokenValue()),
          () -> LOG.debug("The reported token was out of the range. File {}, Range {}", inputFile.filename(), tokenInfo.getTextRange()));
    }
    cpdTokens.save();
  }

}
